#pragma once

#include <vector>
#include <hash_map>
#include "Type.h"
using namespace stdext;
using namespace std;

class Calls {
	private:
		hash_map<Type::Index::Proc,vector<Type::Index::Proc>> callRelation;
		hash_map<Type::Index::Proc,vector<Type::Index::Proc>> revertCallRelation;

		hash_map<Type::Index::Line,Type::Index::Proc> callRelationLineToProc;
		hash_map<Type::Index::Proc,vector<Type::Index::Line>> revertCallRelationProcToLine;
		hash_map<Type::Index::Proc,vector<Type::Index::Line>> allCallLineInProc;

		vector<vector<bool>> callBitMap;
		bool callBitMapSetFlag;
		int number_of_procedure;

	public:
		Calls(void);
		~Calls(void);

		//Set the first Proc calls the second Proc, with the specific line index who calls the second proc.
		//return false, if not set successfully
		bool setCalls(Type::Index::Proc, Type::Index::Line, Type::Index::Proc);
		
		//return a list of all procedure indexes called by a specified procIndex
		//if none, return an empty vector
		//eg. Calls(1,2) Calls(1,3) ---> getCalledBy(1) will return 2,3
		vector<Type::Index::Proc> getCalledBy(Type::Index::Proc);

		//return a list of all procedure indexes called by a specified lineIndex
		//if none, return -1
		//eg. Calls(1,2) and line 5 in procefure 1 calls procedure 2.---> getCalledByLine(5) will return 2
		Type::Index::Proc getCalledByLine(Type::Index::Line);

		//return a list of all procedure indexes that call a specified procIndex
		//if none, return an empty vector
		//eg. Calls(1,3) Calls(2,3) ---> getCallerOf(3) will return 1,2
		vector<Type::Index::Proc> getCallerOf(Type::Index::Proc);

		//return a list of all line indexes that call a specified procIndex
		//if none, return an empty vector
		//eg. Calls(1,3) Calls(2,3) where line 5, line 8 in procedure 1 and line 9 in procedure 2 call procedure 3 ---> getCallerLineOf(3) will return 5,8,9
		vector<Type::Index::Line> getCallerLineOf(Type::Index::Proc);

		vector<Type::Index::Line> getCallStmtOfProc(Type::Index::Proc);
		
		//return true if the first Proc calls the second Proc
		bool isCalls(Type::Index::Proc, Type::Index::Proc);
		
		//return true if the bitMap is set correctly
		bool setCallsBitMap(vector<vector<bool>>);
};